<?php
/* Your initial Class declaration. This file's name must
   be "[class's name].module.php", or, in this case,
   Catlist.module.php
*/

global $AntzRegistry, $AntzFormErrors;
$AntzRegistry = array();
$AntzFormErrors = array();

class Antz extends CMSModule {
/**
 *  Database connection parameters only required if using a different database
 *  from the core. If any of these values (except the port, if using MySQL) are
 *  an empty string, we will use the CMSms config settings.
 *  Default: empty string for all db parameters
 */
    protected $dbType = ''; // possible values: MySQL or PostgreSQL
    protected $dbName = '';
    protected $dbUser = '';
    protected $dbPass = '';
    protected $dbHost = '';
    protected $messageMarker = NULL;

    function MinimumCMSVersion() {return '1.6.1';}
    function HasAdmin() {return false;}
    function GetAdminSection() {return '';}
    function VisibleToAdminUser() {return $this->CheckPermission('Modify '.$this->GetName());}
    function GetName() {return 'Antz';}
    function GetFriendlyName() {return 'Antz toolkit';}
    function GetVersion() {return '1.0.2';}
    function IsPluginModule() {return true;}
    function GetHelp() { return file_get_contents($this->config['root_path'].'/modules/Antz/docs/help.html'); }

    public function getDbType() {
        return $this->dbType;
    }


    public function ContentPostRender(&$content) {
        if($this->messageMarker === NULL) return;
        $msg = Antz::getError().Antz::getSuccess();
        if(strlen($msg)=='') {
            $content = str_replace('<!--###'.$this->messageMarker.'###-->', '', $content);
            return;
        };
        $content = str_replace('<!--###'.$this->messageMarker.'###-->', $msg, $content);
    }




    /**
     * called by hooks in various places to enable other modules to interact with each other ( search in files for "Hookup(" )
     * Accepts: method name, array of parameters
     * returns: array with two indexes: content and values, being any output from the call,
     * 	and whatever values are returned by the module
     * NB: modules are called in alphabetical order
     */
    function Hookup($methodName, $params) {

    // to make it easy for developing, you can turn on debug mode or display output
        $displayOutput = true;
        $debug = false;

        global $gCms;
        $moduleStack = array();
        $output = '';
        $count = 0;
        $module = $gCms->modules['Antz'];

        foreach (array_keys($gCms->modules) as $moduleKey) {
            ob_start();
            $module =& $gCms->modules[$moduleKey];
            if(!$module['installed'] || !$module['active']) continue;
            $module =& $module['object'];

            if(is_object($module) && is_callable(array($module, $methodName))) {
                if($debug) {
                    $moduleStack[$count] = array(
                        'name' => $moduleKey,
                        'friendly_name' => $module->GetFriendlyName(),
                        'pre_params' => $params,
                        'pre_output' => $output
                    );
                }
                $params = $module->$methodName($params, $output);
                if($debug) {
                    $moduleStack[$count]['post_params'] = $params;
                    $moduleStack[$count]['post_output'] = $output;
                }
            }
            $output .= ob_get_contents();
            ob_end_clean();
        };
        $returnParams = array(
            'module_stack' => $moduleStack,
            'params' => $params,
            'output' => $output
        );
        if($debug) {
            echo '<pre>';
            var_dump($moduleStack);
            echo '</pre>';
        };

        if($displayOutput) echo $output;

        return $returnParams;

    }


    public function __construct() {
        parent::CMSModule();
        $dirname = dirname(__FILE__);
        $dirname = str_replace(DIRECTORY_SEPARATOR, '/', $dirname);

        require_once($dirname.'/Antz/Constants.php');
        require_once($dirname.'/Antz/Functions.php');
        require_once($dirname.'/Antz/Input.php');
        require_once($dirname.'/Antz/Filter.php');
        require_once($dirname.'/Antz/Email.php');
        require_once($dirname.'/Antz/Image.php');
        require_once($dirname.'/Antz/Form/Component.php');
        require_once($dirname.'/Antz/Form.php');
        require_once($dirname.'/Antz/IntelliForm.php');

        global $gCms;
        $DB = $this->newDb();
        Antz::register('db', $DB);

        $installed = (bool) $DB->countRows($this->config['db_prefix'].'modules', "module_name = 'Antz' AND `status` = 'installed'");
        if(!class_exists('Antz_User', false) && $installed) {
            $this->removeHooksFromCore();
            $this->addHooksToCore();
            Antz::redir(THIS_PAGE_URL);
        }else if(!$installed) {
            // not installed
                return;
            }




        $USER = Antz_User::getInstance();

        // start our session and user management
        Antz::register('user', $USER);



        //var_dump($_SESSION);

        // prevent pesky messages when refreshing posted data
        Antz_IntelliForm::antirepost();
        Antz_IntelliForm::purge();

        $input = Antz::newObject('Antz_Input');
        Antz::register('input', $input);

        $CRYPT = Antz::newObject('Antz_Crypt');
        Antz::register('crypt', $CRYPT);
        Antz::register('Antz', $this);



        // prepares url parameters into $_GET array when using mod_rewrite
        $this->InterpretUrlParams();

        $this->smarty->assign('thisPageUrl', THIS_PAGE_URL);
   /*
    try{
      throw new exception;
    }catch (exception $e){
      echo '<pre>'.$e->getTraceAsString().'</pre>';
    }*/

    }




    function addPagesToDropMenu(&$sel, $parentId, $depth=0) {
        $DB = Antz::registry('db');
        $pages = $DB->fetchAll("SELECT content_id, content_name FROM {$this->config['db_prefix']}content WHERE parent_id = '{$parentId}' ORDER BY item_order");
        foreach($pages as $k=>$v) {
            $sel->add(str_repeat(' - ', $depth).$v['content_name'], $v['content_id']);
            if($DB->countRows(cms_db_prefix().'content', "parent_id = '{$v['content_id']}'")>0) {
                $this->addPagesToDropMenu($sel, $v['content_id'], $depth+1);
            }
        }
    }




    /**
     * Creates a form component from the provided array
     * Accepts: array defining the field type, name, label, value and options
     * Returns object of descendent Antz_Form_Compontents_$field['type']
     */
    public static function makeFormComponent($field) {
        $Antz = Antz::registry('antz');
        switch($field['type']) {
            case 'text':
            case 'textarea':
            case 'raw':
            case 'submit':
            case 'file':
            case 'password':
            case 'hidden':
            case 'button':
                $className = 'Antz_Form_Components_Input';
                $input = Antz::newObject($className, array($field['type'], $field['name'], $field['label'], $field['value']));
                if(isset($field['extra']) && is_array($field['extra'])) {
                    foreach($field['extra'] as $key3 => $extra) {
                        $command = '$input->'.$extra['command'].'('.implode(',', $extra['params']).');';
                        eval($command);
                    };
                };
                if(isset($field['aftertext'])) $input->addAftertext($field['aftertext']);
                if(isset($field['id'])) $input->setId($field['id']);
                if(isset($field['class'])) $input->addClass($field['class']);
                if(isset($field['setWrap']) && !$field['setWrap']) $input->setWrap(false);
                if(isset($field['showLabel']) && !$field['showLabel']) $input->showLabel(false);
                $input->addAfterText(Antz::getFormError($field['name']));
                if(isset($field['required']) && $field['required']) $input->required(true);
                return $input;
                break;
            case 'select':
                $select = Antz::newObject('Antz_Form_Components_Select', array($field['name'], $field['label'], $field['value']));
                foreach($field['options'] as $optKey=>$optVal) {
                    $select->add($optVal, $optKey);
                };
                if(isset($field['extra']) && is_array($field['extra'])) {
                    foreach($field['extra'] as $key3 => $extra) {
                        $command = '$select->'.$extra['command'].'('.implode(', ', $extra['params']).');';
                        eval($command);
                    };
                };
                if(isset($field['multiple']) && $field['multiple']) $select->setMultiple(true);
                if(isset($field['size'])) $select->setSize($field['size']);
                if(isset($field['aftertext'])) $select->addAftertext($field['aftertext']);
                if(isset($field['id'])) $select->setId($field['id']);
                if(isset($field['class'])) $select->addClass($field['class']);
                if(isset($field['setWrap']) && !$field['setWrap']) $select->setWrap(false);
                if(isset($field['showLabel']) && !$field['showLabel']) $select->showLabel(false);
                $select->addAfterText(Antz::getFormError($field['name']));
                if(isset($field['required']) && $field['required']) $select->required(true);
                return $select;
                break;
            case 'radiogroup':
                $rad = Antz::newObject('Antz_Form_Components_RadioGroup', array($field['name'], $field['value']));
                foreach($field['options'] as $optKey=>$optVal) {
                    $rad->add($optKey, $optVal);
                };
                if(isset($field['extra']) && is_array($field['extra'])) {
                    foreach($field['extra'] as $key3 => $extra) {
                        $command = '$rad->'.$extra['command'].'('.implode(',', $extra['params']).');';
                        eval($command);
                    };
                };
                if(isset($field['aftertext'])) $rad->addAftertext($field['aftertext']);
                if(isset($field['id'])) $rad->setId($field['id']);
                if(isset($field['class'])) $rad->addClass($field['class']);
                if(isset($field['setWrap']) && !$field['setWrap']) $rad->setWrap(false);
                if(isset($field['showLabel']) && !$field['showLabel']) $rad->showLabel(false);
                $rad->addAfterText(Antz::getFormError($field['name']));
                if(isset($field['required']) && $field['required']) $rad->required(true);
                return $rad;
                break;
            case 'checkbox':
                $chk = Antz::newObject('Antz_Form_Components_CheckboxGroup');
                $chk->add($field['name'], $field['label'], $field['value'], $field['checked']);
                if(isset($field['aftertext'])) $chk->addAftertext($field['aftertext']);
                if(isset($field['id'])) $chk->setId($field['id']);
                if(isset($field['class'])) $chk->addClass($field['class']);
                if(isset($field['setWrap']) && !$field['setWrap']) $chk->setWrap(false);
                if(isset($field['showLabel']) && !$field['showLabel']) $chk->showLabel(false);
                $chk->addAfterText(Antz::getFormError($field['name']));
                if(isset($field['required']) && $field['required']) $chk->required(true);
                return $chk;
                break;
            case 'tinymce':
                if(!isset($field['id'])) {
                // cannot make tinymce type without an id
                    $txt = Antz::newObject('Antz_Form_Components_LongTag', array('h1', $Antz->Lang('tinymce_requires_id_set')));
                    return $txt;
                }else {
                    $mces = explode(',', $_SESSION['tiny_live_textareas']);
                    if(!in_array($field['id'], $mces)) $mces[] = $field['id'];
                    $_SESSION['tiny_live_textareas'] = implode(',', $mces);
                    $txt = Antz::newObject('Antz_Form_Components_Input', array('textarea', $field['name'], $field['label'], $field['value']));
                    if(isset($field['extra']) && is_array($field['extra'])) {
                        foreach($field['extra'] as $key3 => $extra) {
                            $command = '$input->'.$extra['command'].'('.implode(',', $extra['params']).');';
                            eval($command);
                        };
                    };
                    if(isset($field['aftertext'])) $txt->addAftertext($field['aftertext']);
                    if(isset($field['id'])) $txt->setId($field['id']);
                    if(isset($field['class'])) $txt->addClass($field['class']);
                    if(!$wrap) $txt->setWrap(false);
                    if(!$label) $txt->showLabel(false);
                    if(isset($field['required']) && $field['required']) $txt->required(true);
                };
                break;
        };
    }

    /**
     * Makes a form with one block, one fieldset and one column from provided params
     * $formFields: array of arrays defining each form field
     * $legend: text to display in legend
     * returns: object of type Antz_Form
     */
    public static function makeRapidForm($formFields, $legend, $intelliFormKey='default') {
        $blocks = Antz::prepareRapidForm($formFields, $legend);
        return Antz::makeForm($blocks, $intelliFormKey);
    }


    /**
     *  Prepares form fields into a format that is interpreted by Antz::makeForm
     *  params: $formFields as array of arrays describing each field, legend text
     *  Returns an array with one block containing one fieldset with supplied legend, containing all form fields
     */

    public static function prepareRapidForm($formFields, $legend) {
        $blocks = array(
            0 => array(
            'type' => 'full',
            'fieldsets' => array(
            0 => array(
            'legend' => $legend,
            'side' => 'left',
            'fields' => $formFields
            )
            )
            )
        );
        return $blocks;
    }

    /**
     * Assembles a form from provided multi-dimensional array.
     * Accepts: array of blocks, containing fieldsets, containing fields
     * Returns: form object
     */
    public static function makeForm($blocks, $intelliFormKey, $wrap=true, $label=true) {
        $Antz = Antz::registry('antz');
        $form = Antz::newObject('Antz_Form', $intelliFormKey);
        foreach($blocks as $k=>$block) {
            $b = $form->add($block['type']);
            foreach($block['fieldsets'] as $key=>$fieldset) {
                $fs = $b->add($fieldset['legend'], $fieldset['side']);
                foreach($fieldset['fields'] as $key2 => $field) {
                    switch($field['type']) {
                        case 'text':
                        case 'textarea':
                        case 'raw':
                        case 'submit':
                        case 'file':
                        case 'password':
                        case 'hidden':
                        case 'button':
                            $input = $fs->addInput($field['type'], $field['name'], $field['label'], $field['value']);
                            if(isset($field['extra']) && is_array($field['extra'])) {
                                foreach($field['extra'] as $key3 => $extra) {
                                    $command = '$input->'.$extra['command'].'('.implode(',', $extra['params']).');';
                                    eval($command);
                                };
                            };
                            if(isset($field['aftertext'])) $input->addAftertext($field['aftertext']);
                            if(isset($field['id'])) $input->setId($field['id']);
                            if(isset($field['class'])) $input->addClass($field['class']);
                            if(!$wrap) $input->setWrap(false);
                            if(!$label) $input->showLabel(false);
                            if(isset($field['required']) && $field['required']) $input->required(true);
                            break;
                        case 'select':
                            $select = $fs->addSelect($field['name'], $field['label'], $field['value']);
                            foreach($field['options'] as $optKey=>$optVal) {
                                if(isset($optVal['options']) && is_array($optVal['options'])) {
                                // doing an optgroup
                                    $optGroup = $select->addOptGroup($optVal['title']);
                                    foreach($optVal['options'] as $optKey=>$optVal) {
                                        $optGroup->add($optVal, $optKey);
                                    };
                                }else {
                                    $select->add($optVal, $optKey);
                                };
                            };
                            if(isset($field['extra']) && is_array($field['extra'])) {
                                foreach($field['extra'] as $key3 => $extra) {
                                    $command = '$select->'.$extra['command'].'('.implode(', ', $extra['params']).');';
                                    eval($command);
                                };
                            };
                            if(isset($field['multiple']) && $field['multiple']) $select->setMultiple(true);
                            if(isset($field['size'])) $select->setSize($field['size']);
                            if(isset($field['aftertext'])) $select->addAftertext($field['aftertext']);
                            if(isset($field['id'])) $select->setId($field['id']);
                            if(isset($field['class'])) $select->addClass($field['class']);
                            if(!$wrap) $select->setWrap(false);
                            if(!$label) $select->showLabel(false);
                            if(isset($field['required']) && $field['required']) $select->required(true);
                            break;
                        case 'radiogroup':
                            $rad = $fs->addRadioGroup($field['name'], $field['value']);
                            foreach($field['options'] as $optKey=>$optVal) {
                                $rad->add($optKey, $optVal);
                            };
                            if(isset($field['extra']) && is_array($field['extra'])) {
                                foreach($field['extra'] as $key3 => $extra) {
                                    $command = '$rad->'.$extra['command'].'('.implode(',', $extra['params']).');';
                                    eval($command);
                                };
                            };
                            if(isset($field['aftertext'])) $rad->addAftertext($field['aftertext']);
                            if(isset($field['id'])) $rad->setId($field['id']);
                            if(isset($field['class'])) $rad->addClass($field['class']);
                            if(isset($field['setWrap']) && !$field['setWrap']) $rad->setWrap(false);
                            if(isset($field['showLabel']) && !$field['showLabel']) $rad->showLabel(false);
                            $rad->addAfterText(Antz::getFormError($field['name']));
                            if(isset($field['required']) && $field['required']) $rad->required(true);
                            break;
                        case 'checkbox':
                            $chk = $fs->addCheckboxGroup($field['name']);
                            $chk->add($field['name'], $field['label'], $field['value'], $field['checked']);
                            if(isset($field['aftertext'])) $chk->addAftertext($field['aftertext']);
                            if(isset($field['id'])) $chk->setId($field['id']);
                            if(isset($field['class'])) $chk->addClass($field['class']);
                            if(!$wrap) $chk->setWrap(false);
                            if(!$label) $chk->showLabel(false);
                            $chk->addAfterText(Antz::getFormError($field['name']));
                            break;
                        case 'tinymce':
                            if(!isset($field['id'])) {
                            // cannot make tinymce type without an id
                                $txt = $fs->addLongTag('h1', $Antz->Lang('tinymce_requires_id_set'));
                            }else {
                                $mces = explode(',', $_SESSION['tiny_live_textareas']);
                                if(!in_array($field['id'], $mces)) $mces[] = $field['id'];
                                $_SESSION['tiny_live_textareas'] = implode(',', $mces);
                                $txt = $fs->addInput('textarea', $field['name'], $field['label'], $field['value']);
                                if(isset($field['extra']) && is_array($field['extra'])) {
                                    foreach($field['extra'] as $key3 => $extra) {
                                        $command = '$input->'.$extra['command'].'('.implode(',', $extra['params']).');';
                                        eval($command);
                                    };
                                };
                                if(isset($field['aftertext'])) $txt->addAftertext($field['aftertext']);
                                if(isset($field['id'])) $txt->setId($field['id']);
                                if(isset($field['class'])) $txt->addClass($field['class']);
                                if(!$wrap) $txt->setWrap(false);
                                if(!$label) $txt->showLabel(false);
                                if(isset($field['required']) && $field['required']) $txt->required(true);
                            };
                            break;
                    }
                }
            }
        }
        unset($blocks);
        return $form;
    }

    public static function newObject($className, $params='') {

        if(class_exists($className)) {
            return Antz::returnObject($className, $params);
        };

        AntzAutoLoad($className);
        if(class_exists($className)) return Antz::returnObject($className, $params);

        throw new Exception('Antz::newObject was requested to find the class '.$className.', but it could not be found');
        return false;

    }

    public static function returnObject($className, $params='') {
        if($params == '') return new $className;
        if(!is_array($params)) return new $className($params);
        if(count($params)==0) return new $className($params);
        if(count($params)==1) return new $className($params[0]);
        if(count($params)==2) return new $className($params[0], $params[1]);
        if(count($params)==3) return new $className($params[0], $params[1], $params[2]);
        if(count($params)==4) return new $className($params[0], $params[1], $params[2], $params[3]);
        if(count($params)==5) return new $className($params[0], $params[1], $params[2], $params[3], $params[4]);
        throw new Exception('Antz::returnObject was requested to instantiate an object with '.count($params).' parameters!');
        while(count($params)>5) array_pop($params);
        return Antz::returnObject($className, $params);
    }

    /**
     * Redirect to another URL
     *
     * @param string $url
     * @param int $code HTTP response code to use in redirect; defaults to 302,
     * Found (same as Location header redirect sent by PHP)
     * @param bool $prependBase
     */
    public static function redir($url, $useJs=true) {
    // redirect
/* debugging
        try{
        throw new exception('e');
        }catch(exception $e){
        	echo '<pre>';
        	echo $e->getTraceAsString();
        	echo '</pre>';
        }
        die($url);
*/
        @header("Location: {$url}");
        if($useJs) echo '<script type="text/javascript">window.location="'.$url.'";</script>';
        die('<a href="'.htmlentities($url).'">Continue >></a>');

    }// end function redirect



    public static function setLastPage($url='') {
        $url = ($url == '') ? THIS_PAGE_URL : $url;
        // add to the stack, only if the top of the stack is not already set to the same value
        if(count($_SESSION['AntzLastPage'])==0)
            $_SESSION['AntzLastPage'][] = $url;
        elseif($_SESSION['AntzLastPage'][count($_SESSION['AntzLastPage'])-1] != $url)
            $_SESSION['AntzLastPage'][] = $url;
    }


    public static function getLastPage($del=true) {
        $user = Antz::registry('user');
        $Antz = Antz::registry('Antz');
        if(!isset($_SESSION['AntzLastPage'])) $_SESSION['AntzLastPage'] = array();
        if( isset($_SESSION['AntzLastPage'][count($_SESSION['AntzLastPage'])-1]) && $_SESSION['AntzLastPage'][count($_SESSION['AntzLastPage'])-1]!='') {
            $lastPage = $_SESSION['AntzLastPage'][count($_SESSION['AntzLastPage'])-1];
            if($del) unset($_SESSION['AntzLastPage'][count($_SESSION['AntzLastPage'])-1]);
        }else {
            if($user->isAdmin())
                $lastPage = $Antz->config['root_url'].'/admin';
            else
                $lastPage = $Antz->config['root_url'];
        };
        return $lastPage;
    }




    /**
     *  redirects to the last page that was set with Antz::setLastPage()
     *  If this has not been set, they are redirected to the default page.
     *  Default page can be suggested as the $url parameter.
     *  If the suggested url parameter is blank, it uses the default last page
     *  defined in globals.ini.
     *  Use Antz::redirect() if you want to force them to a specific page.
     */

    public static function goLastPage() {
        $url = Antz::getLastPage();
        $Antz = Antz::registry('Antz');
        while($url == THIS_PAGE_URL && THIS_PAGE_URL != $Antz->config['root_url']) $url = Antz::getLastPage();
        Antz::redir($url);
    }

    public static function addFormError($key, $msg='') {
        global $AntzFormErrors;
        $Antz = Antz::registry('Antz');
        $AntzFormErrors[$key] = true;
        if($msg == '') $colon = '';
        else $colon = ': ';
        $AntzFormErrors[$key.'_msg'] = $Antz->Lang('error').$colon.$msg;
    }

    public static function isFormError($key) {
        global $AntzFormErrors;
        if(array_key_exists($key, $AntzFormErrors) && $AntzFormErrors[$key]==true) return true;
        else return false;
    }

    public static function getFormError($key) {
        global $AntzFormErrors;
        if(array_key_exists($key.'_msg', $AntzFormErrors)) {
            return '<div class="formError">'.$AntzFormErrors[$key.'_msg'].'</div>';
        }
        else return false;
    }

    public static function addSuccess($log) {
        $user = Antz::registry('user');
        $user->successLog = (isset($user->successLog) && $user->successLog!='')
            ? $user->successLog."<br />".$log
            : $log
        ;
    }

    public static function addError($errorMsg) { // BEGIN function addError
        $user = Antz::registry('user');
        $user->errorLog = (isset($user->errorLog) && $user->errorLog != '')
            ? $user->errorLog.'<br />'.$errorMsg
            : $errorMsg
        ;
    } // END function addError

    public static function getError($delete=true) {
        $user = Antz::registry('user');
        $log = (isset($user->errorLog) && $user->errorLog!='')
            ? '<div id="AntzErrorMsg">'.
            $user->errorLog.
            '&nbsp;&nbsp;<a href="javascript:AntzBase.clearError()"><strong>OK</strong></a>'
            .'</div>'
            : ''
        ;
        if($delete) unset($user->errorLog);
        return $log;
    }

    public static function getSuccess($delete=true) {
        $user = Antz::registry('user');
        $log = (isset($user->successLog)&&$user->successLog!='')
            ? '<div id="AntzSuccessMsg">'.
            $user->successLog.
            '&nbsp;&nbsp;<a href="javascript:AntzBase.clearSuccess()"><strong>OK</strong></a>'
            .'</div>'
            : ''
        ;
        if($delete) unset($user->successLog);
        return $log;
    }

    public static function disable() {
        include('Antz/Disable.php');
        exit;
    }

    /**
     *  Abstracts the access to a global variable that contains objects
     */
    public static function register($name, $obj) {
        global $AntzRegistry;
        $AntzRegistry[strtolower($name)] = $obj;
    }

    /**
     *Prints the contents of the registry to screen
     */
    public static function printRegistry() {
        global $AntzRegistry;
        foreach($AntzRegistry as $keyname=>$obj) {
            echo $keyname.' : '.get_class($obj).'<br />';
        }
    }

    public static function registry($name) {
        global $AntzRegistry;
        $name = strtolower($name);
        if(isset($AntzRegistry[$name])) {
            return $AntzRegistry[$name];
        }else {
            return false;
        }
    }

    public function newDb() {
        if($DB = Antz::registry('db')) return $DB;

        if(!($USER = Antz::registry('user'))) {
            $showErrors = false;
        }else {
            if($USER->isAdmin()) $showErrors = true;
            else $showErrors = false;
        };

        require_once('Antz/Db.php');

        if($this->dbType == 'MySQL' && $this->dbName != '' && $this->dbHost != '' && $this->dbPass != '' && $this->dbUser != '') {
            $dbHost = $this->dbHost;
            $dbName = $this->dbName;
            $dbUser = $this->dbUser;
            $dbPass = $this->dbPass;
            if(!($DB = Antz::newObject('Antz_Db_MySQL', array($dbHost, $dbUser, $dbPass, $dbName, $showErrors)))) {
                throw new Exception('Database parameters provided but connection to MySQL could not be established');
            };
        }else if($this->dbType == 'PostgreSQL' && $this->dbName != '' && $this->dbHost != '' && $this->dbPass != '' && $this->dbUser != '') {
                $dbHost = $this->dbHost;
                $dbName = $this->dbName;
                $dbUser = $this->dbUser;
                $dbPass = $this->dbPass;
                if(!($DB = Antz::newObject('Antz_Db_PostgreSQL', array($dbHost, $dbUser, $dbPass, $dbName, $showErrors)))) {
                    throw new Exception('Database parameters provided but connection to PostgresSQL could not be established');
                };
            }else {
            // using the default CMSms config
                global $gCms;
                $config = $gCms->config;
                $dbHost = $config['db_hostname'];
                $dbUser = $config['db_username'];
                $dbPass = $config['db_password'];
                $dbName = $config['db_name'];

                if($config['dbms'] == 'mysql') {
                    $DB = Antz::newObject('Antz_Db_MySQL', array($dbHost, $dbUser, $dbPass, $dbName, $showErrors));
                    $this->dbType = 'MySQL';
                }else if($config['dbms'] == 'postgres7') {
                        $DB = Antz::newObject('Antz_Db_PostgreSQL', array($dbHost, $dbUser, $dbPass, $dbName, $showErrors));
                        $this->dbType = 'PostgreSQL';
                    }else {
                        die('modules/Antz.module.php - Error: no configuration specifying the database connection type.');
                };
        };

        if(!$DB instanceof Antz_Db) {
            die('Configuration error: database could not be instantiated in modules/Antz.module.php, line '.__LINE__);
        };

        // register in cache for next time
        $DB = Antz::newObject('Antz_Db_Adodb', array($dbHost, $dbUser, $dbPass, $dbName, $showErrors));
        Antz::register('db', $DB);

        return $DB;

    }




    function InstallPostMessage() {
        return 'Installation success.';
    }
    function UninstallPreMessage() {
        return 'Hang tight while we revert the configuration';
    }

    function UninstallPostMessage() {
        return 'Successfully uninstalled';
    }

    function DoAction($action, $id, $params, $returnid=-1) {

        global $gCms;
        if($this->config === NULL) $this->config = $gCms->config;

        if($action=='show_messages') {
            $error = str_replace(array("\n", "\r"), '', Antz::getError());
            $success = str_replace(array("\n", "\r"), '', Antz::getSuccess());
            if($error != '') echo '<script type="text/javascript">
AntzBase.showError(\''.$error.'\');
</script>';
            if($success != '') echo '<script type="text/javascript">
AntzBase.showSuccess(\''.$success.'\');
</script>';

            if($error != '' || $success != '') {
                echo '<div id="AntzMessagesTemp">'.$error.$success.'</div>';
                echo '<script type="text/javascript">
                if(document.getElementById("AntzMessages")){
                    var msgs = document.getElementById("AntzMessagesTemp");
                    var msg = msgs.innerHTML;
                    msgs.innerHTML = "";
                    var msgs = document.getElementById("AntzMessages");
                    msgs.innerHTML = msg;
                    if(msgs.style.display == "none"){
                        msgs.style.display = "block";
                    };
                    
                }
            </script>';

            }

            return;
        };

    /*
    if($action == 'show_messages'){
        echo Antz::getError();
        echo Antz::getSuccess();
        return;
    }*/

        if($action == 'head') {
            echo '<script type="text/javascript" src="'.$this->config['root_url'].'/modules/Antz/js/AntzBase.js"></script>'."\n";
            echo '<link href="'.$this->config['root_url'].'/modules/Antz/css/messages.css" rel="stylesheet" media="all" type="text/css" />';
            echo '<link href="'.$this->config['root_url'].'/modules/Antz/css/forms.css" rel="stylesheet" media="all" type="text/css" />';

            return;
        };


        if($action=='mark_message_position') {
            if($this->messageMarker === NULL) $marker = rand();
            else $marker = $this->messageMarker['marker'];
            echo '<!--###'.$marker.'###-->';
            $this->messageMarker = $marker;

            return;
        }

        die($this->GetName().' does not implement this functionality: '.$action);
    }


    public static function isLaterVersion($subjectVersion, $compareVersion) {
        $sv = explode('.', $subjectVersion);
        $cv = explode('.', $compareVersion);
        while(count($sv) > count($cv)) {
            array_unshift($cv, 0);
        }
        for($i=0; $i<count($sv); $i++) {
            if((int) $sv[$i] > (int) $cv[$i]) return true;
        }
        return false;
    }





    /**
     *  INSTALL AND UNINSTALL METHODS
     */

    function Install() {

        $this->addHooksToCore();

    /*
    // create our tables for configuration
    $DB = Antz::registry('db');
    $sql = <<<SQL

CREATE TABLE prefix_antz_config (
  k VARCHAR(255) NOT NULL PRIMARY KEY,
  v TEXT NOT NULL,
  title VARCHAR(255) NOT NULL,
  field_type VARCHAR(255) NOT NULL
) ENGINE = MYISAM;

SQL;

    $DB->query(str_replace('prefix_', cms_db_prefix(), $sql));

    // create our configuration
    $DB->insert(cms_db_prefix().'antz_config', array('k'=>'phpm_mailer', 'v'=>'mail', 'title'=>'PHP Mailer send method', 'type'=>'text'));

    */



    }
    function Uninstall() {
        $this->removeHooksFromCore();
    }







    private function removeHooksFromCore() {


        global $gCms;

        $incfilename = str_replace(DIRECTORY_SEPARATOR, '/', $gCms->config['root_path']).'/include.php';

        if(!is_writeable($incfilename)) {
            die('Write permission is required for '.$incfilename);
        };


        // remove our requireing of Antz/User.php
        $fc = file_get_contents($incfilename);
        $fcChars = preg_replace('/[^a-zA-Z0-9_\-]/', '', $fc);
        $nameChars = preg_replace('/[^a-zA-Z0-9_\-]/', '', $this->GetName());
        $numOccurrences = 0;
        $numIterations = 0;
        while(strpos($fcChars, 'start'.$nameChars)!==false) {
            $numIterations++;
            $lines = explode("\n", $fc);
            $fileUpdated = false;

            $startLine = false;
            $endLine = false;

            foreach($lines as $lineNumber=>$line) {
                $charsOnly = preg_replace('/[^a-zA-Z0-9_\-\(\{]/', '', $line);
                if(strpos($charsOnly, 'start'.$nameChars)!==false) $startLine = $lineNumber;
                if(strpos($charsOnly, 'end'.$nameChars)!==false) $endLine = $lineNumber;

                if($startLine !== false && $endLine !== false) {
                // we have found a block that was inserted by the module
                    foreach($lines as $k=>$v) {
                        if($k >= $startLine && $k <= $endLine) unset($lines[$k]);
                    };
                    $lines = array_regenerate_keys($lines);
                    $fh = fopen($incfilename, 'w');
                    fwrite($fh, implode("\n", $lines));
                    fclose($fh);
                    $startLine = false;
                    $endLine = false;
                    $numOccurrences++;
                    break 1;
                };
            };

            $fc = file_get_contents($incfilename);
            $fcChars = preg_replace('/[^a-zA-Z0-9_\-]/', '', $fc);

        };// end while finding our name in the file






    }









    private function addHooksToCore() {

        global $gCms;
        $incfilename = str_replace(DIRECTORY_SEPARATOR, '/', $gCms->config['root_path']).'/include.php';
        if(!is_writeable($incfilename)) {
            Antz::addError('Write permission is required for '.$incfilename);
            return false;
        };

        $fileUpdated = false;

        // include our user object before the session is started
        $fc = file_get_contents($incfilename);
        $lines = explode("\n", $fc);
        $fileUpdated = false;
        $startLine = 0;
        $endLine = 0;
        foreach($lines as $lineNumber=>$line) {
            $charsOnly = preg_replace('/[^a-zA-Z0-9_\-\(\)\{\}\$\[\]>;=\',"]/', '', $line);
            if(strpos($charsOnly, '$session_key=substr(md5($dirname),0,8);')!==false) {
            // we found our line
                $startLine = $lineNumber+1;
                $reqFile = 'str_replace(DIRECTORY_SEPARATOR, \'/\', $dirname).\'/modules/Antz/Antz/User.php\'';
                $newLines = array(
                    '// start '.$this->GetName().' module installer at '.date('H:i d M Y'),
                    'require_once('.$reqFile.');',
                    '// end '.$this->GetName().' module installer at '.date('H:i d M Y')
                );

                foreach($newLines as $k=>$v) {
                    $newLineNumber = $startLine + $k;
                    $lines = array_insert($lines, $newLineNumber, $v);
                };

                $newFc = implode("\n", $lines);

                // now we write the contents to the file
                $fh = fopen($incfilename, 'w');
                fwrite($fh, $newFc);
                fclose($fh);

                $fileUpdated = true;
                break 1;
            };
        };

        if(!$fileUpdated) Antz::addError('File '.$incfilename.' was not updated. This file
    requires the following hook inserted to retrieve the form fields when adding and editing content:<br />'.
                implode('<br />', $newLines));

    }




















    /**
     *  Returns a url in a format ready for interpretation by moduleinterface.php
     *  Used mainly for urls in the backend
     */
    function GetUrl($params, $id, $name, $action, $inline=true) {
        global $gCms;
        if(defined('CMS_SECURE_PARAM_NAME') && defined('CMS_USER_KEY')) $secure = '&'.CMS_SECURE_PARAM_NAME.'='.$_SESSION[CMS_USER_KEY];
        else $secure = '';

        $text = $gCms->config['root_url'].'/'.$gCms->config['admin_dir'].'/';
        $text .= 'moduleinterface.php?mact='.$name.','.$id.','.$action.','.($inline == true?1:0);

        foreach ($params as $key=>$value) {
            $text .= '&'.$id.$key.'='.rawurlencode($value);
        }
        return $text.$secure;
    }





    function getUrlByAlias($alias) {
        global $gCms;

        if($gCms->config['assume_mod_rewrite']) {
            $url = $gCms->config['root_url'].'/'.$alias.$gCms->config['page_extension'];
        }else if($gCms->config['internal_pretty_urls']) {
                $url = $gCms->config['root_url'].'/index.php/'.$alias.$gCms->config['page_extension'];
            }else {
                $url = $gCms->config['root_url'].'/index.php?'.$gCms->config['query_var'].'='.$alias;
            }
        return $url;

    }

    function getUrlById($id) {
        $DB = Antz::registry('db');
        global $gCms;

        $id = (int) $id;
        $cData = $DB->fetchRow("SELECT content_alias FROM {$gCms->config['db_prefix']}content WHERE content_id = {$id}");
        if(!is_array($cData) || count($cData)==0) {
            return '';
        }
        
        return Antz::getUrlByAlias($cData['content_alias']);

        $manager =& $gCms->GetHierarchyManager();
        $node =& $manager->sureGetNodeById($id);
        if(!is_object($node)) return '';
        $content =& $node->GetContent();
        if (isset($content)) {
            if ($content->GetURL() != '') {
                $url = $content->GetURL();
            }else {
                return '';
            };
        }else {
            return '';
        };
        if(strpos($url, 'http')!==0) $url = $gCms->config['root_url'].'/'.$url;
        else echo strpos($url, 'http').' strpos<br />';
        return $url;
    }

    function AddParamsToUrl($url, $params, $htmlentities = false) {
        if($htmlentities) $amp = '&amp;';
        else $amp = '&';

        global $gCms;
        $config = $gCms->config;

        $configParts = parse_url($config['root_url']);

        // do not use mod_rewrite rules if in admin pages
        $adminDirFound = false;
        $dirs = str_replace($config['root_url'], '', $url);
        $dirs = ltrim($dirs, '/');
        $dirs = explode('/', $dirs);
        if($dirs[0] == $config['admin_dir']) $adminDirFound = true;

        $urlParts = parse_url($url);

        if(!array_key_exists('scheme', $urlParts)) {
            $urlParts['scheme'] = $configParts['scheme'];
        }
        if(!array_key_exists('host', $urlParts)) {
            $urlParts['host'] = $configParts['host'];
        }

        if(!$adminDirFound && ($config['url_rewriting']=='mod_rewrite' || $config['url_rewriting']=='internal')) {
        // using mod_rewrite
            $pathParts = explode('/', ltrim($urlParts['path'], '/'));

            $newParams = array();
            foreach($params as $k=>$v) {
                $newParams[] = urlencode($k).'/'.urlencode($v);
            }

            if(count($pathParts)==0) {
            // no existing parameters
                $urlParts['path'] = '/'.ltrim($urlParts['path'], '/').implode('/', $newParams);
            }else {
            // there are existing parameters, the last of which is probably the page slug
                $alias = array_pop($pathParts);
                $urlParts['path'] = '/'.trim(implode('/', $pathParts), '/').rtrim(implode('/', $newParams), '/').'/'.$alias;
            }

            // build the new url
            if(strlen(trim($urlParts['query']))>0) $join = '?';
            else $join = '';

            $url = $urlParts['scheme'].'://'.$urlParts['host'].'/'.ltrim($urlParts['path'], '/').$join.$urlParts['query'];

        }else {
        // not using mod_rewrite

            $newQuery = http_build_query($params, '', $amp);
            if(strlen($urlParts['query'])==0) {
            // only these parameters
                $urlParts['query'] = $newQuery;
            }else {
                $urlParts['query'] .= $amp.$newQuery;
            }
            // build the new url
            if(strlen(trim($urlParts['query']))>0) $join = '?';
            else $join = '';

            $url = $urlParts['scheme'].'://'.$urlParts['host'].'/'.ltrim($urlParts['path'], '/').$join.$urlParts['query'];
        }


        return $url;
    }

    function InterpretUrlParams($url='') {
        if($url == '') $url = THIS_PAGE_URL;
        $params = $this->getUrlParamsAsArray($url);
        foreach($params as $k=>$v) {
            $_GET[$k] = $v;
        }
    }


    function getUrlParamsAsArray($url) {
        global $gCms;
        $config = $gCms->config;

        $params = array();

        $urlParts = parse_url($url);

        // parse classic url params first
        if(strlen($urlParts['query'])>0) {
            $queries = explode('&', $urlParts['query']);
            foreach($queries as $k=>$v) {
                $key = substr($v, 0, strpos($v, '='));
                $value = substr($v, strpos($v, '=')+1);
                $params[urldecode($key)] = urldecode($value);
            }
        }

        // parse params compiled into url path
        if($config['url_rewriting']=='mod_rewrite' || $config['url_rewriting']=='internal') {
            $urls = explode('/', trim($urlParts['path'], '/'));
            $urls = array_reverse($urls);
            $value = '';
            for($i=1; $i<count($urls); $i++) {
                if($i%2==0) {
                // this is a key
                    $params[$urls[$i]] = urldecode($value);
                }else {
                // this is a value
                    $value = $urls[$i];
                }
            }
        }
        return $params;
    }



    function GetAdminUrl($params, $id, $name, $action, $inline=true) {
        $text = $this->config['root_url'].'/'.$this->config['admin_dir'];
        $text .= '/moduleinterface.php?mact='.$name.','.$id.','.$action.','.($inline == true?1:0);
        foreach ($params as $key=>$value) {
            $text .= '&'.$id.$key.'='.rawurlencode($value);
        }
        return $text;
    }




}



?>
